#pragma once

#pragma warning(disable:4996)

#include "MZFC.h"

class CPoint;
class CSize;
class CRect;
class CDC;
class CBrush;

class MZFC_API CSize : public SIZE
{
public:	
	CSize()	{cx=0; cy=0;}

	CSize(SIZE sz)	{cx=sz.cx; cy=sz.cy;}

	CSize(long x, long y)	{cx=x; cy=y;}


	//operator
	inline bool operator==(SIZE size) 	{ return (size.cx== cx && size.cy == cy);	}

	inline bool operator!=(SIZE size) 	{ return (size.cx != cx && size.cy != cy);	}	

	inline void operator+=(SIZE size)	{ cx += size.cx; cy+=size.cy;}	

	inline void operator-=(SIZE size)	{ cx -= size.cx; cy-=size.cy;}		

	inline CSize operator+(SIZE size) 	{return CSize (cx+size.cx,cy+size.cy);}

	inline CSize operator-(SIZE size) 	{	return CSize (cx-size.cx,cy-size.cy);	}

	inline CSize operator-() 	{ return CSize(-cx, -cy); }

	inline CPoint operator+(POINT point) ;

	inline CPoint operator-(POINT point) ;
};


class MZFC_API CPoint : public POINT
{
public:
	CPoint (long  lx, long ly)	{ x=lx; y=ly;}

	CPoint()  { x=0; y=0;}	

	CPoint(POINT pt)	{x=pt.x; y=pt.y;}

	CPoint::CPoint(DWORD dwPoint)
	{
		x = (short)LOWORD(dwPoint);
		y = (short)HIWORD(dwPoint);
	}

	operator POINT() { return *this;}

	inline BOOL operator==(POINT point) 
	{
		return (point.x== x && point.y==y);
	}

	inline BOOL operator!=(POINT point) 
	{
		return (point.x!= x || point.y!=y);
	}

	inline void operator+=(SIZE size)
	{ 
		x+=size.cx; 
		y+=size.cy;
	}

	inline void operator-=(SIZE size)
	{ 
		x-=size.cx; 
		y-=size.cy;
	}

	inline void operator+=(POINT point)
	{
		x+=point.x; 
		y+=point.y;
	}

	inline void operator-=(POINT point)
	{ 
		x-=point.x; 
		y-=point.y;
	}


	inline CPoint operator+(SIZE size) 
	{
		return CPoint(size.cx+x,size.cy+y);
	}

	inline CPoint operator-(SIZE size) 
	{
		return CPoint(size.cx-x,size.cy-y);
	}

	inline CPoint operator-() 
	{
		return CPoint(-x,-y);
	}

	inline CPoint operator+(POINT point) 
	{
		return CPoint(point.x+x,point.y+y);
	}


	inline CSize operator-(POINT point) 
	{
		return CSize(x-point.x,y-point.y);
	}
};



class MZFC_API CRect : public RECT
{
public:
	CRect()
	{ 
		CRect (0,0,0,0);
	}

	CRect (CPoint ptLt, CPoint ptBr)
	{
		CRect(ptLt.x,ptLt.y,ptBr.x,ptBr.y);	
	}

	CRect (int x, int y, int Right, int Bottom)
	{
		left=x;
		top=y;
		right=Right;
		bottom=Bottom;
	}

	CRect(POINT point, SIZE size)
	{ 
		right = (left = point.x) + size.cx;
		bottom = (top = point.y) + size.cy; 
	}

	CRect(POINT topLeft, POINT bottomRight)
	{ 
		left = topLeft.x; 
		top = topLeft.y;
		right = bottomRight.x; 
		bottom = bottomRight.y; 
	}

	CRect::CRect(const RECT& srcRect)
	{	
		::CopyRect(this, &srcRect); 
	}

	inline int  Width()	
	{	
		return (int )right-left;
	}

	inline int Height()	
	{	
		return (int )bottom-top;
	}

	inline CSize Size() 			{ return CSize(right - left, bottom - top); }
	inline CPoint  TopLeft()			{ return CPoint(left,top); }
	inline CPoint  BottomRight()		{ return CPoint(right,bottom); }

	inline CPoint  CenterPoint() 	{ return CPoint((left + right) / 2, (top + bottom) / 2); }
	inline operator LPRECT()			{ return this; }
	inline operator LPCRECT() 	{ return this; }
	inline BOOL  IsRectEmpty() 	{ return ::IsRectEmpty(this); }
	inline BOOL  IsRectNull() 	{ return (left == 0 && right == 0 && top == 0 && bottom == 0); }
	inline BOOL  PtInRect(POINT point) 		{ return ::PtInRect(this, point); }
	inline void  SetRect(int x1, int y1, int x2, int y2)	{ ::SetRect(this, x1, y1, x2, y2); }
	inline void  SetRect(POINT topLeft, POINT bottomRight)	{ ::SetRect(this, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); }
	inline void  SetRectEmpty()		{ ::SetRectEmpty(this); }
	inline void  CopyRect(LPCRECT lpSrcRect)		{ ::CopyRect(this, lpSrcRect); }
	inline BOOL  EqualRect(LPCRECT lpRect) 	{ return ::EqualRect(this, lpRect); }
	inline void  InflateRect(int x, int y)			{ ::InflateRect(this, x, y); }
	inline void  InflateRect(SIZE size)			{ ::InflateRect(this, size.cx, size.cy); }
	inline void  DeflateRect(int x, int y)			{ ::InflateRect(this, -x, -y); }
	inline void  DeflateRect(SIZE size)			{ ::InflateRect(this, -size.cx, -size.cy); }
	inline void  OffsetRect(int x, int y)			{ ::OffsetRect(this, x, y); }
	inline void  OffsetRect(POINT point)			{ ::OffsetRect(this, point.x, point.y); }
	inline void  OffsetRect(SIZE size)				{ ::OffsetRect(this, size.cx, size.cy); }
	inline BOOL  IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2)	{ return ::IntersectRect(this, lpRect1, lpRect2);}
	inline BOOL  UnionRect(LPCRECT lpRect1, LPCRECT lpRect2)		{ return ::UnionRect(this, lpRect1, lpRect2); }
	inline void  operator=( RECT& srcRect)					{ ::CopyRect(this, &srcRect); }
	inline BOOL  operator==( RECT& rect) 				{ return ::EqualRect(this, &rect); }
	inline BOOL  operator!=( RECT& rect) 				{ return !::EqualRect(this, &rect); }
	inline void  operator+=(POINT point)							{ ::OffsetRect(this, point.x, point.y); }
	inline void  operator+=(SIZE size)								{ ::OffsetRect(this, size.cx, size.cy); }
	inline void  operator+=(LPCRECT lpRect)						{ InflateRect(lpRect); }
	inline void  operator-=(POINT point)							{ ::OffsetRect(this, -point.x, -point.y); }
	inline void  operator-=(SIZE size)								{ ::OffsetRect(this, -size.cx, -size.cy); }
	inline void  operator-=(LPCRECT lpRect)						{ DeflateRect(lpRect); }
	inline void  operator&=( RECT& rect)						{ ::IntersectRect(this, this, &rect); }
	inline void  operator|=( RECT& rect)						{ ::UnionRect(this, this, &rect); }
	inline CRect  operator+(POINT pt) 	{ CRect rect(*this); ::OffsetRect(&rect, pt.x, pt.y); return rect; }
	inline CRect  operator-(POINT pt) 	{ CRect rect(*this); ::OffsetRect(&rect, -pt.x, -pt.y); return rect; }
	inline CRect  operator+(SIZE size) 	{ CRect rect(*this); ::OffsetRect(&rect, size.cx, size.cy); return rect; }
	inline CRect  operator-(SIZE size) 	{ CRect rect(*this); ::OffsetRect(&rect, -size.cx, -size.cy); return rect; }
	inline BOOL  SubtractRect(LPCRECT lpRectSrc1, LPCRECT lpRectSrc2)	{ return ::SubtractRect(this, lpRectSrc1, lpRectSrc2); }
	inline CRect operator&(const RECT& rc) { CRect rect; ::IntersectRect(&rect, this, &rc);	return rect; }
	inline CRect operator|(const RECT& rc)	{ CRect rect; ::UnionRect(&rect, this, &rc);	return rect; }

	inline void  InflateRect(LPCRECT lpRect)
	{
		left -= lpRect->left;
		top -= lpRect->top;
		right += lpRect->right;
		bottom += lpRect->bottom;
	}

	void MoveToXY(int x, int y)
	{
		right += x - left;
		bottom += y - top;

		left = x;
		top = y;
	}

	inline void  InflateRect(int l, int t, int r, int b)
	{
		left -= l;
		top -= t;
		right += r;
		bottom += b;
	}

	inline void  DeflateRect(LPCRECT lpRect)
	{
		left += lpRect->left;
		top += lpRect->top;
		right -= lpRect->right;
		bottom -= lpRect->bottom;
	}

	inline void  DeflateRect(int l, int t, int r, int b)
	{
		left += l;
		top += t;
		right -= r;
		bottom -= b;
	}

	inline CRect  MulDiv(int nMultiplier, int nDivisor) 
	{
		return CRect(
			::MulDiv(left, nMultiplier, nDivisor),
			::MulDiv(top, nMultiplier, nDivisor),
			::MulDiv(right, nMultiplier, nDivisor),
			::MulDiv(bottom, nMultiplier, nDivisor));
	}
};

CPoint CSize::operator+(POINT point) 
{ 
	return CPoint(point.x+cx, point.y+cy);
}

CPoint CSize::operator-(POINT point) 
{ 
	return CPoint(point.x-cx, point.y-cy);
}



class MZFC_API CFont
{
public:
	HFONT m_hFont;

	CFont(HFONT hFont = NULL) 
	{  m_hFont=hFont;}

	~CFont()
	{
		if(m_hFont != NULL && !::DeleteObject(m_hFont))
			m_hFont = NULL;
	}

public:

	operator HFONT() {return m_hFont;}  

	HFONT  GetFont(){ return m_hFont;}

	void Attach(HFONT hFont)
	{
		if( m_hFont != NULL)
			::DeleteObject(m_hFont);
		m_hFont = hFont;
	}

	HFONT Detach()
	{
		HFONT hFont = m_hFont;
		m_hFont = NULL;
		return hFont;
	}

	void DeleteObject()
	{
		if( m_hFont != NULL)
			::DeleteObject(m_hFont);
	}

	HFONT CreateFontIndirect(const LOGFONT* lpLogFont)
	{
		ASSERT(m_hFont == NULL);
		m_hFont = ::CreateFontIndirect(lpLogFont);
		return m_hFont;
	}


	BOOL GetStockFont( int nStockFont )
	{

		HFONT hFont = ( HFONT )::GetStockObject( nStockFont );
		if ( !hFont) 	return FALSE;
		Attach( hFont );
		return TRUE;
	}


	int GetLogFont(LOGFONT* pLogFont) 
	{
		ASSERT(m_hFont != NULL);
		return ::GetObject(m_hFont, sizeof(LOGFONT), pLogFont);
	}

	bool GetLogFont(LOGFONT& LogFont) 
	{
		ASSERT(m_hFont != NULL);
		return (::GetObject(m_hFont, sizeof(LOGFONT), &LogFont) == sizeof(LOGFONT));
	}
};

//-------------------------------
// CPen class
//-------------------------------
class MZFC_API CPen
{

public:
	HPEN m_hPen;	
	CPen(HPEN hPen=NULL)	{ m_hPen=hPen;}

	~CPen()
	{
		DeleteObject();
	}

	BOOL IsValidPen() {return !(m_hPen==NULL);}

	HPEN GetPen() { if (! IsValidPen()) return NULL; return m_hPen;}

	HPEN CreatePen(int fnPenStyle=PS_SOLID,int nWidth=1,COLORREF clColor=RGB(0,0,0))
	{
		if (IsValidPen()) return NULL;
		m_hPen=::CreatePen(fnPenStyle,nWidth,clColor);
		return m_hPen;
	}

	HPEN CreatePenIndirect( LOGPEN* lplgpen)
	{
		if (IsValidPen()) return NULL;
		m_hPen=::CreatePenIndirect(lplgpen);
		return m_hPen;
	}

	BOOL DeleteObject()
	{
		if (! IsValidPen()) return NULL;
		BOOL brs = ::DeleteObject((HPEN)m_hPen);
		if(brs)	m_hPen = NULL;
		return brs;
	}


	int GetLogPen(LOGPEN* pLogPen) 
	{
		if (!IsValidPen()) return NULL;
		return ::GetObject(m_hPen, sizeof(LOGPEN), pLogPen);
	}
};

//----------------------------------
//CBrush class
//----------------------------------

class MZFC_API CBrush
{
public:
	HBRUSH m_hBrush;

	CBrush(HBRUSH hBrush = NULL) 
	{ 
		m_hBrush=hBrush;
	}

	~CBrush()	{	DeleteObject();	}


	HBRUSH GetBrush() { return m_hBrush; }

	HBRUSH GetSafeHandle() { return GetBrush();} //compatibilidad con MFC

	operator HBRUSH() { return GetSafeHandle();}
	BOOL IsValidBrush() {return !(m_hBrush==NULL);}

	CBrush(COLORREF crColor)
	{	
		Attach(::CreateSolidBrush(crColor));
	}
	void Attach(HBRUSH hBrush)
	{
		if(m_hBrush != NULL)
			::DeleteObject(m_hBrush);
		m_hBrush = hBrush;
	}

	HBRUSH Detach()
	{
		HBRUSH hBrush = m_hBrush;
		m_hBrush = NULL;
		return hBrush;
	} 

	HBRUSH CreateSolidBrush(COLORREF crColor)
	{
		if (IsValidBrush()) return NULL;
		m_hBrush = ::CreateSolidBrush(crColor);
		return m_hBrush;
	}


	HBRUSH CreatePatternBrush(HBITMAP hBitmap)
	{
		if ( IsValidBrush()) return NULL;
		m_hBrush = ::CreatePatternBrush(hBitmap);
		return m_hBrush;
	}

	HBRUSH CreateDIBPatternBrush( void* lpPackedDIB, UINT nUsage=DIB_PAL_COLORS)
	{
		if (lpPackedDIB == NULL) return NULL;
		m_hBrush=::CreateDIBPatternBrushPt(lpPackedDIB, nUsage);
		return m_hBrush;
	}

	HBRUSH CreateSysColorBrush(int nIndex)
	{
		if (IsValidBrush()) return NULL;
		m_hBrush = ::GetSysColorBrush(nIndex);
		return m_hBrush;
	}

	BOOL DeleteObject()
	{
		if (!IsValidBrush()) return NULL;
		BOOL bres = ::DeleteObject(m_hBrush);
		if(bres)
			m_hBrush = NULL;
		return bres;
	}

	int GetLogBrush(LOGBRUSH* pLogBrush) 
	{
		if (! IsValidBrush()) return NULL;
		return ::GetObject(m_hBrush, sizeof(LOGBRUSH), pLogBrush);
	}
};

//-------------------------------------------
// CBitmap class
//-------------------------------------------

class MZFC_API CBitmap
{

public:

	HBITMAP m_hBitmap;
	CBitmap(HBITMAP hBitmap = NULL) { m_hBitmap=hBitmap;}

	~CBitmap() { DeleteObject();}

	BOOL IsValidBitmap() { return !(m_hBitmap== NULL);}

	HBITMAP GetBitMap() { if (IsValidBitmap()) return m_hBitmap; return NULL;}

	HBITMAP GetSafeHandle() { if (IsValidBitmap()) return m_hBitmap; return NULL;}
	HBITMAP LoadBitmap(HINSTANCE hInsTance,LPCTSTR lpBitmapName)
	{
		if (IsValidBitmap()) return NULL;
		m_hBitmap = ::LoadBitmap(hInsTance,lpBitmapName);
		return m_hBitmap;
	}

	HBITMAP LoadOEMBitmap(UINT nIDBitmap) 
	{
		if (IsValidBitmap()) return NULL;
		m_hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap));
		return m_hBitmap;
	}

	HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitcount,  void* lpBits)
	{
		if (IsValidBitmap()) return NULL;
		m_hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitcount, lpBits);
		return m_hBitmap;
	}

	BOOL DeleteObject()
	{
		if (!IsValidBitmap()) return NULL;
		BOOL bres = ::DeleteObject(m_hBitmap);
		if(bres)
			m_hBitmap = NULL;
		return bres;
	}

	int GetBitmap(BITMAP* pBitMap) 
	{
		if (!IsValidBitmap()) return NULL;
		return ::GetObject(m_hBitmap, sizeof(BITMAP), pBitMap);
	}

	BOOL GetBitmap(BITMAP& bm) 
	{
		if (!IsValidBitmap()) return NULL;
		return (::GetObject(m_hBitmap, sizeof(BITMAP), &bm) == sizeof(BITMAP));
	}

	BOOL GetSize(SIZE& size) 
	{
		if (!IsValidBitmap()) return NULL;
		BITMAP bm;
		if(!GetBitmap(&bm))
			return false;
		size.cx = bm.bmWidth;
		size.cy = bm.bmHeight;
		return true;
	}

	CSize GetSize() 
	{
		if (!IsValidBitmap()) return CSize(0,0);
		BITMAP bm;
		if(!GetBitmap(&bm))
			return CSize(0,0);
		return CSize(bm.bmWidth,bm.bmHeight);
	}

	DWORD SetBitmapBits(DWORD dwCount,  void* lpBits)
	{
		if (!IsValidBitmap()) return NULL;
		return ::SetBitmapBits(m_hBitmap, dwCount, lpBits);
	}

	HBITMAP CreateCompatibleBitmap(HDC hDC, int nWidth, int nHeight)
	{
		if (IsValidBitmap()) return NULL;
		m_hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight);
		return m_hBitmap;
	}

	HBITMAP CreateDIBSection(HDC hDC,  BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset)
	{
		if (IsValidBitmap()) return NULL;
		m_hBitmap = ::CreateDIBSection(hDC, lpbmi, uColorUse, ppvBits, hSection, dwOffset);
		return m_hBitmap;
	}
};


class MZFC_API CDC 
{
public:
	HDC m_hDC;
public:

	CDC(HDC hDC=NULL)
	{ 
		m_hDC=hDC;
	}

	~CDC()
	{
		if (m_hDC != NULL)
		::DeleteDC(m_hDC);
	}

	BOOL IsValidHandle() {return m_hDC != NULL;}
	//---------------------------------------------------------------------
	int SaveDC()
	{
		if (IsValidHandle())
			return ::SaveDC(m_hDC);
		return 0;
	}

	operator HDC() {return m_hDC;}
	BOOL RestoreDC(int nSavedDC)
	{
		if (IsValidHandle())
			return ::RestoreDC(m_hDC, nSavedDC);
		return 0;
	}

	int GetDeviceCaps(int nIndex) 
	{
		if (IsValidHandle())
			return ::GetDeviceCaps(m_hDC, nIndex);
		return 0;
	}

	COLORREF GetNearestColor(COLORREF crColor) 
	{ 
		if (IsValidHandle())
			return ::GetNearestColor(m_hDC, crColor); 
		else
			return 0;
	}



	HFONT SelectFont(HFONT hFont)
	{

		return ((HFONT)::SelectObject((m_hDC), (HGDIOBJ)(HFONT)(hFont)));
	}




	HFONT SelectObject(CFont cf)
	{
		if (IsValidHandle())
			return (HFONT) ::SelectObject(m_hDC,(HFONT)cf.GetFont());
		return NULL;
	}
	//---------------------------------------------------------------------
	HPEN SelectObject(CPen* cp)
	{
		if (IsValidHandle())
			return (HPEN) ::SelectObject(m_hDC,(HPEN)cp->GetPen());
		return NULL;
	}

	HBRUSH SelectObject(CBrush* cb)
	{
		if (IsValidHandle())
			return (HBRUSH) ::SelectObject(m_hDC,(HBRUSH)cb->GetBrush());
		return NULL;
	}
	//--------------------------------------------------------------------
	HBITMAP SelectObject(CBitmap* cb)
	{
		if (IsValidHandle())
			return (HBITMAP) ::SelectObject(m_hDC,(HBITMAP)cb->GetBitMap());
		return NULL;
	}

	//---------------------------------------------------------------------


	HGDIOBJ SelectStockObject(int fnObjec)
	{
		if (IsValidHandle())
			return ::SelectObject(m_hDC,GetStockObject(fnObjec));
		return NULL;
	}

	CPen GetCurrentPen() 
	{
		if (IsValidHandle())
			return CPen((HPEN)::GetCurrentObject(m_hDC, OBJ_PEN));
		return CPen(NULL);

	}
	CBrush GetCurrentBrush() 
	{
		if (IsValidHandle())
			return CBrush((HBRUSH)::GetCurrentObject(m_hDC, OBJ_BRUSH));
		return CBrush();
	}
	/*CPalette GetCurrentPalette() 
	{
	if (IsValidHandle())
	return CPaletteHandle((HPALETTE)::GetCurrentObject(m_hDC, OBJ_PAL));
	}
	CFont GetCurrentFont() 
	{
	if (IsValidHandle())
	return CFontHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT));
	}*/
	CBitmap GetCurrentBitmap() 
	{
		if (IsValidHandle())
			return CBitmap((HBITMAP)::GetCurrentObject(m_hDC, OBJ_BITMAP));
		return CBitmap();
	}

	HDC CreateDC(LPCTSTR lpszDriverName, LPCTSTR lpszDeviceName, LPCTSTR lpszOutput,  DEVMODE* lpInitData)
	{
		if (IsValidHandle()) return m_hDC;
		m_hDC = ::CreateDC(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData);
		return m_hDC;
	}

	HDC CreateCompatibleDC(HDC hDC = NULL)
	{
		if (IsValidHandle()) return m_hDC;
		m_hDC = ::CreateCompatibleDC(hDC);
		return m_hDC;
	}

	BOOL DeleteDC()
	{
		if (!IsValidHandle()) return FALSE;
		BOOL bres = ::DeleteDC(m_hDC);
		if(bres)
			m_hDC = NULL;
		return bres;
	}

	//--------------------------------------------------------------------------------


	COLORREF GetBkColor()
	{
		if (IsValidHandle())
			return ::GetBkColor(m_hDC);
		return RGB(0,0,0);
	}
	int GetBkMode() 
	{
		if (IsValidHandle())
			return ::GetBkMode(m_hDC);
		return 0;

	}

	int GetROP2() 
	{
		if (IsValidHandle())
			return ::GetROP2(m_hDC);
		return 0;
	}
	int GetStretchBltMode() 
	{
		if (IsValidHandle())
			return ::GetStretchBltMode(m_hDC);
		return 0;
	}
	COLORREF GetTextColor() 
	{
		if (IsValidHandle())
			return ::GetTextColor(m_hDC);
		return RGB(0,0,0);
	}

	COLORREF SetBkColor(COLORREF crColor)
	{
		if (IsValidHandle())
			return ::SetBkColor(m_hDC, crColor);
		return RGB(0,0,0);
	}
	int SetBkMode(int nBkMode)
	{
		if (IsValidHandle())
			return ::SetBkMode(m_hDC, nBkMode);
		return 0;
	}

	int SetROP2(int nDrawMode)
	{
		if (IsValidHandle())
			return ::SetROP2(m_hDC, nDrawMode);
		return 0;
	}
	int SetStretchBltMode(int nStretchMode)
	{
		if (IsValidHandle())
			return ::SetStretchBltMode(m_hDC, nStretchMode);
		return 0;
	}
	COLORREF SetTextColor(COLORREF crColor)
	{
		if (IsValidHandle())
			return ::SetTextColor(m_hDC, crColor);
		return RGB(0,0,0);
	}

	// ---------------------------------------------------------------------

	BOOL GetViewportOrg(LPPOINT lpPoint) 
	{
		if (IsValidHandle())
			return ::GetViewportOrgEx(m_hDC, lpPoint);
		return 0;
	}

	// Viewport Origin
	BOOL SetViewportOrg(int x, int y, LPPOINT lpPoint = NULL)
	{
		if (IsValidHandle())
			return ::SetViewportOrgEx(m_hDC, x, y, lpPoint);
		return FALSE;
	}
	BOOL SetViewportOrg(POINT point, LPPOINT lpPointRet = NULL)
	{
		if (IsValidHandle())
			return SetViewportOrg(point.x, point.y, lpPointRet);
		return FALSE;
	}
	BOOL OffsetViewportOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL)
	{
		if (IsValidHandle())
			return ::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, lpPoint);
		return FALSE;
	}

	//---------------------------------------------------------------------------
	BOOL GetViewportExt(LPSIZE lpSize) 
	{
		if (IsValidHandle())
			return ::GetViewportExtEx(m_hDC, lpSize);
		return FALSE;
	}

	// Window Origin
	BOOL GetWindowOrg(LPPOINT lpPoint) 
	{
		if (IsValidHandle())
			return ::GetWindowOrgEx(m_hDC, lpPoint);
		return FALSE;
	}
	BOOL SetWindowOrg(int x, int y, LPPOINT lpPoint = NULL)
	{
		if (IsValidHandle())
			return ::SetWindowOrgEx(m_hDC, x, y, lpPoint);
		return FALSE;
	}
	BOOL SetWindowOrg(POINT point, LPPOINT lpPointRet = NULL)
	{
		if (IsValidHandle())
			return SetWindowOrg(point.x, point.y, lpPointRet);
		return FALSE;
	}

	BOOL GetWindowExt(LPSIZE lpSize) 
	{
		if (IsValidHandle())
			return ::GetWindowExtEx(m_hDC, lpSize);
		return FALSE;
	}

	//--------------------------------------------------------------------------
	BOOL FillRgn(HRGN hRgn, HBRUSH hBrush)
	{
		if (IsValidHandle())
			return ::FillRgn(m_hDC, hRgn, hBrush);
		return FALSE;
	}

	// ----------------------------------------------------------------------------
	int GetClipBox(LPRECT lpRect) 
	{
		if (IsValidHandle())
			return ::GetClipBox(m_hDC, lpRect);
		return 0;
	}

	BOOL RectVisible(LPCRECT lpRect) 
	{
		if (IsValidHandle())
			return ::RectVisible(m_hDC, lpRect);
		return FALSE;
	}
	int SelectClipRgn(HRGN hRgn)
	{
		if (IsValidHandle())
			return ::SelectClipRgn(m_hDC, (HRGN)hRgn);
		return 0;
	}
	int ExcludeClipRect(int x1, int y1, int x2, int y2)
	{
		if (IsValidHandle())
			return ::ExcludeClipRect(m_hDC, x1, y1, x2, y2);
		return 0;
	}
	int ExcludeClipRect(LPCRECT lpRect)
	{
		if (IsValidHandle())
			return ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
		return 0;
	}

	int IntersectClipRect(int x1, int y1, int x2, int y2)
	{
		if (IsValidHandle())
			return ::IntersectClipRect(m_hDC, x1, y1, x2, y2);
		return 0;
	}
	int IntersectClipRect(LPCRECT lpRect)
	{
		if (IsValidHandle())
			return ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
		return 0;
	}

	//--------------------------------------------------------------------------
	BOOL GetCurrentPosition(LPPOINT lpPoint) 
	{
		if (IsValidHandle())
			return ::GetCurrentPositionEx(m_hDC, lpPoint);
		return FALSE;
	}
	BOOL MoveTo(int x, int y, LPPOINT lpPoint = NULL)
	{
		if (IsValidHandle())
			return ::MoveToEx(m_hDC, x, y, lpPoint);
		return FALSE;

	}
	BOOL MoveTo(POINT point, LPPOINT lpPointRet = NULL)
	{
		if (IsValidHandle())
			return MoveTo(point.x, point.y, lpPointRet);
		return FALSE;
	}
	BOOL LineTo(int x, int y)
	{
		if (IsValidHandle())
			return ::LineTo(m_hDC, x, y);
		return FALSE;
	}
	BOOL LineTo(POINT point)
	{
		if (IsValidHandle())
			return LineTo(point.x, point.y);
		return FALSE;
	}

	BOOL DrawLine(POINT pointOr,POINT pointTar)
	{
		if (IsValidHandle())
		{
			MoveTo(pointOr);
			LineTo(pointTar);
			return TRUE;
		}
		return FALSE;
	}

	BOOL DrawLine(POINT pointOr,POINT pointTar,COLORREF clColor)
	{
		if (IsValidHandle())
		{
			CPen Color;
			Color.CreatePen(PS_SOLID,1,clColor);
			CPen pOldPen=CPen(SelectObject(&Color));
			MoveTo(pointOr);
			LineTo(pointTar);
			SelectObject(&pOldPen);	
			return TRUE;
		}
		return FALSE;
	}

	void DrawRect(CRect* rclt,COLORREF clLT,COLORREF clBR)
	{
		DrawLine(CPoint(rclt->left,rclt->top),CPoint(rclt->left,rclt->bottom),clLT);
		DrawLine(CPoint(rclt->left,rclt->top+1),CPoint(rclt->right,rclt->top+1),clLT);
		DrawLine(CPoint(rclt->right,rclt->top+1),CPoint(rclt->right,rclt->bottom),clBR);
		DrawLine(CPoint(rclt->left,rclt->bottom-1),CPoint(rclt->right,rclt->bottom-1),clBR);
	}

	BOOL Polyline(LPPOINT lpPoints, int nCount)
	{
		if (IsValidHandle())
			return ::Polyline(m_hDC, lpPoints, nCount);
		return FALSE;
	}

	// ----------------------------------------------------------------------

	void FillRect(LPCRECT lprc,CBrush* pBruhs)
	{
		if (IsValidHandle())
			::FillRect(m_hDC,lprc,(HBRUSH)pBruhs->GetBrush());
	}

	void FillRect(LPCRECT lprc,HBRUSH hBruhs)
	{
		if (IsValidHandle())
			::FillRect(m_hDC,lprc,hBruhs);
	}

	BOOL InvertRect(LPCRECT lpRect)
	{
		if (IsValidHandle())
			return ::InvertRect(m_hDC, lpRect);
		return FALSE;
	}

	BOOL drawIcon(int x, int y, HICON hIcon)
	{
		if (IsValidHandle())
			return ::DrawIcon(m_hDC, x, y, hIcon);
		return FALSE;
	}

	BOOL drawIcon(POINT point, HICON hIcon)
	{
		if (IsValidHandle())
			return ::DrawIcon(m_hDC, point.x, point.y, hIcon);
		return FALSE;
	}
	BOOL DrawIconEx(int x, int y, HICON hIcon, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
	{
		if (IsValidHandle())
			return ::DrawIconEx(m_hDC, x, y, hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
		return FALSE;
	}
	BOOL DrawIconEx(POINT point, HICON hIcon, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
	{
		if (IsValidHandle())
			return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
		return FALSE;
	}

	void DrawFocusRect(LPCRECT lpRect)
	{
		if (IsValidHandle())
			::DrawFocusRect(m_hDC, lpRect);
	}

	BOOL Ellipse(int x1, int y1, int x2, int y2)
	{
		if (IsValidHandle())
			return ::Ellipse(m_hDC, x1, y1, x2, y2);
		return FALSE;
	}
	BOOL Ellipse(LPCRECT lpRect)
	{
		if (IsValidHandle())
			return ::Ellipse(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
		return FALSE;
	}


	BOOL Polygon(LPPOINT lpPoints, int nCount)
	{
		if (IsValidHandle())
			return ::Polygon(m_hDC, lpPoints, nCount);
		return FALSE;
	}

	BOOL Rectangle(int x1, int y1, int x2, int y2)
	{
		if (IsValidHandle())
			return ::Rectangle(m_hDC, x1, y1, x2, y2);
		return FALSE;
	}
	BOOL Rectangle(LPCRECT lpRect)
	{
		if (IsValidHandle())
			return ::Rectangle(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
		return FALSE;
	}
	BOOL RoundRect(int x1, int y1, int x2, int y2, int x3, int y3)
	{
		if (IsValidHandle())
			return ::RoundRect(m_hDC, x1, y1, x2, y2, x3, y3);
		return FALSE;
	}
	BOOL RoundRect(LPCRECT lpRect, POINT point)
	{
		if (IsValidHandle())
			return ::RoundRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, point.x, point.y);
		return FALSE;
	}

	//------------------------------------------------------------------------------------
	BOOL PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop)
	{
		if (IsValidHandle())
			return ::PatBlt(m_hDC, x, y, nWidth, nHeight, dwRop);
		return FALSE;
	}
	BOOL PatBlt(CRect rc, DWORD dwRop)
	{
		if (IsValidHandle())
			return ::PatBlt(m_hDC, rc.left,rc.top, rc.Width(),rc.Height(), dwRop);
		return FALSE;
	}
	BOOL BitBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC,
		int xSrc, int ySrc, DWORD dwRop)
	{
		if (IsValidHandle())
			return ::BitBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop);
		return FALSE;
	}
	BOOL BitBlt(CRect rc, HDC hSrcDC,
		int xSrc, int ySrc, DWORD dwRop)
	{
		if (IsValidHandle())
			return ::BitBlt(m_hDC, rc.left, rc.top, rc.right, rc.bottom, hSrcDC, xSrc, ySrc, dwRop);
		return FALSE;
	}
	BOOL StretchBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop)
	{
		if (IsValidHandle())
			return ::StretchBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop);
		return FALSE;
	}
	COLORREF GetPixel(int x, int y) 
	{
		if (IsValidHandle())
			return ::GetPixel(m_hDC, x, y);
		return FALSE;
	}
	COLORREF GetPixel(POINT point) 
	{
		if (IsValidHandle())
			return ::GetPixel(m_hDC, point.x, point.y);
		return FALSE;
	}
	COLORREF SetPixel(int x, int y, COLORREF crColor)
	{
		if (IsValidHandle())
			return ::SetPixel(m_hDC, x, y, crColor);
		return FALSE;
	}
	COLORREF SetPixel(POINT point, COLORREF crColor)
	{
		if (IsValidHandle())
			return ::SetPixel(m_hDC, point.x, point.y, crColor);
		return FALSE;
	}

	BOOL MaskBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, HBITMAP hMaskBitmap, int xMask, int yMask, DWORD dwRop)
	{
		if (IsValidHandle())
			return ::MaskBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, hMaskBitmap, xMask, yMask, dwRop);
		return FALSE;
	}

	//------------------------------------------------------------------------------------------

	BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lpRect, LPCTSTR lpszString, UINT nCount = -1, LPINT lpDxWidths = NULL)
	{
		if (IsValidHandle())
		{
			if(nCount == -1)
				nCount = lstrlen(lpszString);
			return ::ExtTextOut(m_hDC, x, y, nOptions, lpRect, lpszString, nCount, lpDxWidths);
		}
		return FALSE;
	}

	int DrawText(LPCTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat)
	{
		if (IsValidHandle())
			return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat);
		return 0;
	}

	int  DrawText(LPCTSTR lpstrText, LPRECT lpRect,UINT uFormat=0)
	{
		return DrawText(lpstrText, _tcslen(lpstrText), lpRect, uFormat);
	}


	BOOL GetTextExtent(LPCTSTR lpszString, int nCount, LPSIZE lpSize) 
	{
		if (IsValidHandle())
		{
			if(nCount == -1)
				nCount = lstrlen(lpszString);
			return ::GetTextExtentPoint32(m_hDC, lpszString, nCount, lpSize);
		}
		return FALSE;
	}


	CSize GetTextExtent(LPCTSTR lpszString, int nCount) 
	{
		CSize sc;
		GetTextExtent(lpszString, nCount, &sc); 
		return sc;
	}

	UINT GetTextAlign() 
	{
		if (IsValidHandle())
			return ::GetTextAlign(m_hDC);
		return 0;
	}
	UINT SetTextAlign(UINT nFlags)
	{
		if (IsValidHandle())
			return ::SetTextAlign(m_hDC, nFlags);
		return 0;
	}
	int GetTextFace(LPTSTR lpszFacename, int nCount) 
	{
		if (IsValidHandle())
			return ::GetTextFace(m_hDC, nCount, lpszFacename);
		return 0;
	}
	int GetTextFaceLen() 
	{
		if (IsValidHandle())
			return ::GetTextFace(m_hDC, 0, NULL);
		return 0;
	}

	BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics) 
	{
		if (IsValidHandle())
			return ::GetTextMetrics(m_hDC, lpMetrics);
		return FALSE;
	}

	int GetTextCharacterExtra() 
	{
		if (IsValidHandle())
			return ::GetTextCharacterExtra(m_hDC);
		return 0;
	}
	int SetTextCharacterExtra(int nCharExtra)
	{
		if (IsValidHandle())
			return ::SetTextCharacterExtra(m_hDC, nCharExtra);
		return 0;
	}

	// -----------------------------------------------------------------------------
	BOOL DrawEdge(LPRECT lpRect, UINT nEdge, UINT nFlags)
	{
		if (IsValidHandle())
			return ::DrawEdge(m_hDC, lpRect, nEdge, nFlags);
		return FALSE;
	}
	BOOL DrawFrameControl(LPRECT lpRect, UINT nType, UINT nState)
	{
		if (IsValidHandle())
			return ::DrawFrameControl(m_hDC, lpRect, nType, nState);
		return FALSE;
	}

	//-------------------------------------------------------------------------------
	BOOL ScrollDC(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate)
	{
		if (IsValidHandle())
			return ::ScrollDC(m_hDC, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate);
		return FALSE;
	}

	BOOL GetCharWidth32(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) 
	{
		if (IsValidHandle())
			return ::GetCharWidth32(m_hDC, nFirstChar, nLastChar, lpBuffer);
		return FALSE;
	}

	BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABC lpabc) 
	{
		if (IsValidHandle())
			return ::GetCharABCWidths(m_hDC, nFirstChar, nLastChar, lpabc);
		return FALSE;
	}
	DWORD GetFontData(DWORD dwTable, DWORD dwOffset, LPVOID lpData, DWORD cbData) 
	{
		if (IsValidHandle())
			return ::GetFontData(m_hDC, dwTable, dwOffset, lpData, cbData);
		return FALSE;
	}

	//-------------------------------------------------------------------------------------
	int Escape(int nEscape, int nInputSize, LPCSTR lpszInputData,
		int nOutputSize, LPSTR lpszOutputData)
	{
		if (IsValidHandle())
			return ::ExtEscape(m_hDC, nEscape, nInputSize, lpszInputData, nOutputSize, lpszOutputData);
		return FALSE;
	}

	//-----------------------------------------------------------------------------------
	int SetDIBitsToDevice(int x, int y, DWORD dwWidth, DWORD dwHeight, int xSrc, int ySrc, UINT uStartScan, UINT cScanLines,  VOID* lpvBits,  BITMAPINFO* lpbmi, UINT uColorUse)
	{
		if (IsValidHandle())
			return ::SetDIBitsToDevice(m_hDC, x, y, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
		return 0;
	}
	int StretchDIBits(int x, int y, int nWidth, int nHeight, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight,  VOID* lpvBits,  BITMAPINFO* lpbmi, UINT uColorUse, DWORD dwRop)
	{
		if (IsValidHandle())
			return ::StretchDIBits(m_hDC, x, y, nWidth, nHeight, xSrc, ySrc, nSrcWidth, nSrcHeight, lpvBits, lpbmi, uColorUse, dwRop);
		return 0;
	}
	UINT GetDIBColorTable(UINT uStartIndex, UINT cEntries, RGBQUAD* pColors) 
	{
		if (IsValidHandle())
			return ::GetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors);
		return 0;
	}
	UINT SetDIBColorTable(UINT uStartIndex, UINT cEntries,  RGBQUAD* pColors)
	{
		if (IsValidHandle())
			return ::SetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors);
		return 0;
	}


	void FillSolidRect(LPCRECT lpRect, COLORREF clr)
	{

		if (!IsValidHandle()) return ;
		::SetBkColor(m_hDC, clr);
		::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL);
	}

	void FillSolidRect(int x, int y, int cx, int cy, COLORREF clr)
	{
		if (!IsValidHandle()) return ;

		::SetBkColor(m_hDC, clr);
		CRect rect(x, y, x + cx, y + cy);
		::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
	}

	void Draw3dRect(LPCRECT lpRect,	COLORREF clrTopLeft, COLORREF clrBottomRight)
	{
		Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left,
			lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
	}

	void Draw3dRect(int x, int y, int cx, int cy,
		COLORREF clrTopLeft, COLORREF clrBottomRight)
	{
		FillSolidRect(x, y, cx - 1, 1, clrTopLeft);
		FillSolidRect(x, y, 1, cy - 1, clrTopLeft);
		FillSolidRect(x + cx, y, -1, cy, clrBottomRight);
		FillSolidRect(x, y + cy, cx, -1, clrBottomRight);
	}

	void DrawTextAjust(CRect rc,LPCTSTR lpString, UINT uFormatDrop, UINT uFormatNormal)
	{
		TCHAR m_cadBreak[64];
		memset(m_cadBreak,0,64);
		lstrcpy(m_cadBreak,lpString);
		int contt;
		int cont =contt=lstrlen(m_cadBreak);
		CSize coor=GetTextExtent(m_cadBreak,cont);
		if ( coor.cx > rc.Width())
		{
			rc.left+=1;
			while(cont > 1 )
			{
				TCHAR m_scadtemp[64];
				memset(m_scadtemp,0x00,64);
				lstrcpy(m_scadtemp,m_cadBreak);
				lstrcat(m_scadtemp,_T("..."));
				CSize coor=GetTextExtent(m_scadtemp,lstrlen(m_scadtemp));
				if(coor.cx > rc.Width())
					*(m_cadBreak+cont)=NULL;
				else
					break;
				cont--;
			}
			lstrcat(m_cadBreak,_T("..."));
			rc.right+=3;

			DrawText(m_cadBreak,rc,uFormatDrop);
		}
		else
			DrawText(lpString,rc,uFormatNormal);

	}

	static CBrush* HalftGray()
	{
		const WORD GrayBmp[] = {0x0055, 0x00AA, 0x0055, 0x00AA,
			0x0055, 0x00AA, 0x0055, 0x00AA};
		HBITMAP hGray= ::CreateBitmap(8, 8, 1, 1, &GrayBmp);
		CBrush* cb=new CBrush();
		cb->CreatePatternBrush(hGray);
		DeleteObject((HGDIOBJ)hGray);
		return cb;

	}
};


class MZFC_API CPaintDC : public CDC
{
	HWND m_hWnd;
	PAINTSTRUCT m_ps;
public:

	CPaintDC(HWND hWnd=NULL)
	{
		if(hWnd == NULL || ::IsWindow(hWnd))
		{
			m_hWnd = hWnd;
			m_hDC = ::BeginPaint(hWnd, &m_ps);
		}
	}

	~CPaintDC()
	{
		if (m_hDC != NULL && ::IsWindow(m_hWnd))
			::EndPaint(m_hWnd, &m_ps);

	}
};

